<template>
  <div class="cmsUploadFile" :class="disabled?'noneBtn':''">
    <el-upload class="upload-demo fill span18 small-payment-upload" :before-upload="(file)=>uploadPartOne(file)" action :multiple="isMultiple()" list-type="picture-card" :show-file-list="false" :before-remove="(file)=>removeFile(file)" :file-list="list" :disabled="disabled" :limit="limit" :on-exceed="handleExceed">
      <i class="el-icon-plus"></i>
      <div>
        <!-- <el-button v-if="!disabled"
                   size="small"
                   :loading="isLoading"
                   type="primary">
          <i class="iconfont icon-shangchuan"></i> {{buttonLabel}}
        </el-button>-->
      </div>
      <div slot="tip" v-if="!disabled" class="el-upload__tip">{{info}}</div>
    </el-upload>
    <div class="file-list">
      <ul class="el-upload-list el-upload-list--picture-card" style="display: flex;flex-direction: row">
        <li v-for="(item, index) in list" :key="index" :tabindex="index" class="el-upload-list__item is-ready flex-hv-center">
          <div v-if="list.length>0">
            <img :src="item.src" alt="#" class="el-upload-list__item-thumbnail">
            <span class="el-upload-list__item-actions">
              <span v-if='showPreview' class="el-upload-list__item-preview" @click="preview(item)">
                <i class="el-icon-zoom-in"></i>
              </span>
              <span class="el-upload-list__item-delete" @click="download(item)">
                <i class="el-icon-download"></i>
              </span>
              <span class="el-upload-list__item-delete" v-if="!disabled" @click="removeFile(item)">
                <i class="el-icon-delete"></i>
              </span>
            </span>
          </div>
        </li>
      </ul>
    </div>

    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <div style="max-height: 600px;overflow-y: auto" class="WholeScroll flex-hv-center">
        <img class="fileViewImg" :src="dialogImageUrl" alt="#" />
      </div>
    </el-dialog>
  </div>
</template>

<script>
import file from '@/api/file'
import { v4 as uuidv4 } from 'uuid';
import { Base64 } from 'js-base64'
const PREVIEW_URL = process.env.VUE_APP_FILE_PREVIEW
import msgUtil from '@/utils/msgUtil'
import { addTable, editTable, deleteTable, uploadFile, preview, download, getTablePage, packZip } from '@/api/file'


export default {
  name: "UploadFile",
  components: {
    'el-image-viewer': () => import('element-ui/packages/image/src/image-viewer')
  },
  props: {
    detailId: {
      type: String,
      default: ''
    },
    fileList: {
      type: Array,
      default: () => []
    },
    fileLimit: {
      type: Number,
      default: 99
    },
    fileSystem: {
      type: Object,
      default: () => {
        return { sys: '', module: '', part: "" }
      }
    },
    // 数量限制
    limit: {
      type: Number,
      default: 5,
    },
    type: {
      type: String,
      default: 'single'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    info: {
      type: String,
      default: ''
    },
    buttonLabel: {
      type: String,
      default: '点击上传'
    },
    //文件類型校验方法-若需要校验，从父组件传入此方法
    checkFiles: {
      type: Function,
      default: (file) => {
        return true
      }
    },
    //获取文件后的回调函数-从父组件传入此方法
    getFilesCb: {
      type: Function,
      default: () => { }
    },
    //获取文件后的回调函数-从父组件传入此方法
    uploadCb: {
      type: Function,
      default: () => { }
    },
    showPreview: {
      type: Boolean,
      default: true
    }
  },
  watch: {
    'detailId': {
      handler(val) {
        this.isSaveFile = false
        if (this.oldUuid && !val) {
        } else {
          if (val) {
            this.init()
          } else {
            this.$set(this, 'list', [])
          }
        }
      },
      deep: true
    },
    'fileSystem': {
      handler(val) {
        if (this.oldUuid) {
        } else {
          this.init()
        }
      },
      deep: true
    },
    'fileList': {
      handler(val) {
        this.$set(this, 'list', val)
      },
      deep: true
    },
  },
  data() {
    return {
      isSaveFile: false,
      oldUuid: null,
      isLoading: false,
      dialogImageUrl: '',
      dialogVisible: false,
      list: [],
      images: [],
      detailId2: '',
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    isMultiple() {
      if (this.type == 'single') {
        return false
      } else {
        return true
      }
    },
    saveAll(formId) {
      this.detailId2 = formId
      this.isSaveFile = true
      this.list.forEach(it => {
        this.beforeUpload(it.file, this.fileSystem.part, 'save')
      })
      this.list = []
    },
    cancelAll() {
      this.list = []
    },
    init() {
      if (!this.detailId) {
        this.oldUuid = this.uuid()
        return
      }
      this.$publicUpload.getFile(this.fileSystem.module, this.detailId, this.fileSystem.part)
        .then(res => {
          const items = res.data || []
          const arr = []
          items.forEach(o => {
            arr.push({
              realName: o.name,
              name: o.name,
              size: o.size,
              ext: o.ext,
              id: o.id
            })
          })
          this.list = arr
          this.setImg()
        })
    },
    setImg() {
      this.list.forEach(file => {
        if (process.env.NODE_ENV == 'development') {
          file.src = `${process.env.VUE_APP_BASE_API}api/file-server/file/download?id=` + file.id
        } else {
          file.src = `${process.env.VUE_APP_BASE_API}/file-server/file/download?id=` + file.id
        }
        // this.$httpGet('/file-server/file/preview?id='+file.id).then(data => {
        //   file.src = data.data
        // })
      })
      this.$forceUpdate()
      console.log(this.list, 'sssssssssssss')
    },

    previewImgURl(id) {
      this.$httpGet('/file-server/file/preview?id=' + id).then(url => {
        this.$set(this, 'dialogImageUrl', url.data)
        this.dialogVisible = true;
      }).catch(res => {
        console.log(res)
      })
    },
    handleExceed(files, fileList) {
      this.$messageWarning(`最多上传${this.fileLimit}张图片`)
    },
    uploadPartOne(file) {
      this.beforeUpload(file, this.fileSystem.part, 'upload')
    },
    // 上传文件前
    async beforeUpload(file, part, actionType) {
      if (!file) {
        return
      }
      let type = file.name.split('.')[file.name.split('.').length - 1]
      if (type !== 'jpg' && type !== 'jpeg' && type !== 'png' && type !== 'svg' && type !== 'JPG' && type !== 'JPEG' && type !== 'PNG' && type !== 'SVG') {
        this.$messageWarning('请上传图片')
        return
      }
      if (actionType == 'upload') {
        let arr = JSON.parse(JSON.stringify(this.list))
        arr.push({})
        if ((arr.length) > this.fileLimit) {
          this.$messageWarning(`最多上传${this.fileLimit}张图片`)
          return
        }
      }
      if (actionType == 'save') {
        if ((this.list.length) > this.fileLimit) {
          this.$messageWarning(`最多上传${this.fileLimit}张图片`)
          return
        }
      }
      if (!file) {
        return
      }
      await this.compressImg(file, { maxWidth: 700, maxHeight: 700 }).then(newFile => {
        file = newFile
      })
      /*
    *公共上传方法
    * */
      this.$set(this, 'isLoading', true)
      let form = this.detailId2
      if (actionType == 'upload') {
        form = this.uuid()
      }
      this.$store.state.settings.uploadLoading = false
      await this.$publicUpload.uploadFile(file, form, this.fileSystem.module, part, file.name,).then(async res => {
        if (res.code === 200) {
          if (this.type === 'single') {
            if (this.list.length != 0) {
              //先解绑
              await this.$publicUpload.removeFile(this.list[0].id)
              this.list = [{
                file: file,
                realName: file.name,
                name: file.name,
                size: file.size,
                ext: file.ext,
                id: res.data[0],
              }]
            } else {
              this.list = [{
                file: file,
                realName: file.name,
                name: file.name,
                size: file.size,
                ext: file.ext,
                id: res.data[0],
              }]
            }
          }
          if (this.type === 'mul') {
            this.list.push({
              file: file,
              realName: file.name,
              name: file.name,
              size: file.size,
              ext: file.ext,
              id: res.data[0],
            })
          }
          this.uploadCb(res)
          this.$nextTick(() => {
            this.setLastImg()
          })
        } else {
          msgUtil.error2(res.data.message)
        }
        this.change()
      }).catch(res => {
        this.$set(this, 'isLoading', false)
        this.$store.state.settings.uploadLoading = true
        msgUtil.error2('上传文件前-请求失败!')
      }).finally(() => {
        this.$set(this, 'isLoading', false)
        this.$store.state.settings.uploadLoading = true
      })
    },
    setLastImg() {
      let file = this.list[this.list.length - 1]
      if (process.env.NODE_ENV == 'development') {
        file.src = `${process.env.VUE_APP_BASE_API}api/file-server/file/download?id=` + file.id
      } else {
        file.src = `${process.env.VUE_APP_BASE_API}/file-server/file/download?id=` + file.id
      }
      // this.$httpGet('/file-server/file/preview?id='+file.id).then(data => {
      //   file.src = `${process.env.VUE_APP_BASE_API}`+data.data
      //   window.open(data.data);
      // })
      this.$forceUpdate()
    },
    // 删除文件时解绑文件
    removeFile(file) {
      let arr = JSON.parse(JSON.stringify(this.list))
      for (let i in arr) {
        if (arr[i].id == file.id) {
          console.log(i)
          arr.splice(i, 1)
          this.$publicUpload.removeFile(file.id)
          this.change()
          this.list = []
          this.$set(this, 'list', arr)
          console.log(this.list)
          this.setImg()
          return
        }
      }
      // this.list.forEach((item, index) => {
      //   if (file.id == item.id) {
      //     this.list.splice(index,1)
      //   }
      // })
      // this.$forceUpdate()
      // this.$publicUpload.removeFile(file.id)
      // this.change()
    },
    download(file) {
      this.$publicUpload.checkFile(file.id, file.realName)
    },
    change() {
      this.$emit('change', this.list)
    },
    notImage(item) {
      if (item.ext == 'jpg' || item.ext == 'jpeg' || item.ext == 'png' || item.ext == 'gif') {
        return false
      }
      return false
    },
    imageData() {
      return []
    },
    preview(file) {
      let that = this
      if (file.src) {
        this.$nextTick(() => {
          this.dialogImageUrl = file.src;
          this.dialogVisible = true;
        })
      } else {
        // const id =  'img_'+ file.id
        // const img = document.getElementById(id)
        // console.log(img)
        this.previewImgURl(file.id)
      }
    },
    uuid() {
      return uuidv4().split('-')[0]
    },
    compressImg(file, { maxWidth, maxHeight }) {
      const fileName = file.name
      const img = new Image()
      const reader = new FileReader()
      reader.readAsDataURL(file)
      return new Promise((resolve, reject) => {
        reader.onload = (event) => {
          img.src = String(event.target.result)
        }
        img.onload = () => {
          const { width: originWidth, height: originHeight } = img
          let targetWidth = originWidth
          let targetHeight = originHeight
          if (originWidth > maxWidth || originHeight > maxHeight) {
            if (originWidth / originHeight > 1) {
              // 宽图片
              targetWidth = maxWidth
              targetHeight = Math.round(maxWidth * (originHeight / originWidth))
            } else {
              // 高图片
              targetHeight = maxHeight
              targetWidth = Math.round(maxHeight * (originWidth / originHeight))
            }
          }
          const canvas = document.createElement('canvas')
          const context = canvas.getContext('2d')
          canvas.width = targetWidth
          canvas.height = targetHeight
          context.clearRect(0, 0, targetWidth, targetHeight)
          context.drawImage(img, 0, 0, targetWidth, targetHeight)
          const base64 = canvas.toDataURL('image/png', 0.2)
          const arr = base64.split(',')
          const mime = arr[0].match(/:(.*?);/)[1]
          const suffix = mime.split('/')[1]
          const bStr = atob(arr[1])
          let n = bStr.length
          const u8arr = new Uint8Array(n)
          while (n--) {
            u8arr[n] = bStr.charCodeAt(n)
          }
          const file = new File([u8arr], `${fileName}`, {
            type: mime
          })
          resolve(file)
        }
      })
    },
    isImage(file) {
      // 定义允许的图片MIME类型数组
      const imageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'];
      // 检查文件类型是否在我们定义的图片MIME类型数组中
      return imageTypes.includes(file.type);
    }
  }
}
</script>

<style scoped lang="scss">
.cmsUploadFile {
  width: 100%;
  .fileList {
    display: flex;
    align-items: center;
    justify-content: space-between;
    .fileName {
      display: flex;
      align-items: center;
      cursor: pointer;
      span {
        display: block;
        width: 247px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
  }
}
.file-name {
  text-align: center;
  line-height: 140px;
}
.file-list {
  width: 100%;
  flex-direction: row;
}
.flex-hv-center {
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
<style lang="scss">
.noneBtn {
  .small-payment-upload {
    display: none;
  }
}
.fileViewImg {
  /*width: 100%;*/
  max-height: 500px;
}
</style>
